
import { initState } from './observe'
import Watcher from './observe/watcher';
import { complier } from './util'

import { h, patch, render } from '../vdom'

/**
 * 
 * @param {*} options 用户传入的数据
 */
function Vue(options){
  this._init(options); // 初始化vue
  
}

Vue.prototype._init = function(options){
  // vue中的初始化 this.$options 表示vue中的参数
  let vm = this;
  vm.$options = options;

  // MVVM原理 需要将数据重新初始化
  initState(vm); // data computed watch

  // 初始化工作
  if (vm.$options.el) {
    vm.$mount()
  }

}

/**
 * 获取dom节点
 * @param {*} el 
 */
function query(el){
  if (typeof el === 'string') {
    return document.querySelector(el);
  }
  // 传的是dom节点
  return el;
}



Vue.prototype._update = function(vnode){
  console.log('更新次数')
  // 用用户传入的数据，去更新视图
  let vm = this;
  let el = vm.$el;
  
  let preVnode = vm.preVnode;
  if (!preVnode) {
    // 初次渲染
    vm.preVnode = vnode; // 把上一次的节点保存起来
    render(vnode, el);
  }else{
    // vue的更新操作 更新渲染
    vm.$el = patch(vm.preVnode, vnode);
  }
  
}

// 渲染yem
Vue.prototype.$mount = function(){
  let vm = this;
  let el = vm.$options.el; // 获取元素
  el = vm.$el = query(el); // 获取当前挂载的节点

  // 渲染是通过， watcher来渲染的
  // 渲染watcher  
  // vue2.0 组件级别更新

  // 更新组件，渲染的逻辑
  let updateComponent = () => {
    vm._update(vm._render()); // 更新组件
  }

  new Watcher(vm, updateComponent);

  // 需要让数据更改了，重新

}

/**
 * expr 方法名
 * handler 方法实现
 */
Vue.prototype.$watch = function(expr, handler){
  // 原理 创建一个watcher  user: true用户自己定义的
  let vm = this
  new Watcher(vm, expr, handler, {user: true})
}

Vue.prototype._render = function(){
  let vm = this;
  // 获取用户的render方法
  let render = vm.$options.render;
  let vnode = render.call(vm, h);
  return vnode;
}


export default Vue